<template>
  <div class="home">
    <dv-full-screen-container class="container">
      <div class="header">
        <div class="title">
          <div class="logo">
            <svg-icon class-name="innolux-icon" icon-class="innolux" :style="{width: `${80 / dpr}px`, height: `${40 / dpr}`}" />
            <div :style="{ height: `${60 / dpr}`, marginTop: `${13 / dpr}px`}" style="font-size: 1rem;font-weight: 700;background: linear-gradient(120deg, #409EFF, #83D0FF); -webkit-background-clip: text; color: transparent;">群志光電智慧物流</div>
          </div>
          <!-- <h1>智能仓储管理看板</h1> -->
          <!-- <h1 :style="{lineHeight: `${60 / dpr}px`}" style="position: relative;">
            <div :style="{top: `${ -(5 / dpr) }px`}" style="position: absolute;left: 13%;color: #fff;font-size: 24px;font-weight: bold;"> -->
            <h1 style="position: relative;">
              <div style="position: absolute;left: 13%;color: #fff;top: 10px;font-size: 24px;font-weight: bold;">
              <el-tooltip :content="this.$t('productManagement.language')" effect="dark" placement="bottom">
                <lang-select id="lang-select" class="right-menu-item hover-effect" />
              </el-tooltip>
            </div>
            <svg-icon style="position: absolute;left: 31%;" class-name="valeotext-icon" icon-class="valeotext" :style="{width: `${120 / dpr}px`, height: `${60 / dpr}`}"/>
            {{  $t('bigTitle')  }}
          </h1>
          <div class="time">{{ time }}</div>
        </div>
      </div>
      <div class="body">
        <div class="left">
          <div class="left-top">
            <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
              <div style="display: flex;flex-direction: column;height: 100%;">
                <div class="basic-title">{{  $t('productManagement.title5')  }}</div>
                <div style="width: 100%;" id="storage-usage"></div>
              </div>
            </dv-border-box-10>
          </div>
          <div class="left-bottom">
            <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
              <div style="display: flex;flex-direction: column;height: 100%;">
                <div class="basic-title">{{  $t('productManagement.outIn')  }}</div>
                <div style="display: flex;flex-direction: column;height: 100%;flex: 1;">
                  <div style="flex: 1;">
                    <div id="hour-fifo"></div>
                  </div>
                  <div style="flex: 1;">
                    <div id="day-fifo"></div>
                  </div>
                </div>
              </div>
            </dv-border-box-10>
          </div>
        </div>
        <div class="center">
          <div class="center-center">
            <div class="four-item">
              <div class="specific-item">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div>{{  $t('productManagement.title1')  }}</div>
                  <count-to :start-val="0" :end-val="manageTitle?.allStorageCount" :duration="1500" class="card-panel-num" />
                </dv-border-box-10>
              </div>
              <div class="specific-item">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div>{{  $t('productManagement.title2')  }}</div>
                  <count-to :start-val="0" :end-val="manageTitle?.outPalletCount" :duration="1500" class="card-panel-num" />
                </dv-border-box-10>
              </div>
              <div class="specific-item">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div>{{  $t('productManagement.title3')  }}</div>
                  <!-- <count-to :start-val="0" :end-val="manageTitle?.TRS ? manageTitle?.TRS * 100 : 0" suffix="%" :duration="1500" class="card-panel-num" /> -->
                  <count-to :start-val="0" :end-val="98" suffix="%" :duration="1500" class="card-panel-num" />
                </dv-border-box-10>
              </div>
              <div class="specific-item">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div>{{  $t('productManagement.title4')  }}</div>
                  <count-to :start-val="0" :end-val="manageTitle?.availableStorages" :duration="1500" class="card-panel-num" />
                </dv-border-box-10>
              </div>
            </div>
            <div class="four-item">
              <div class="specific-item">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div>{{  $t('productManagement.title5')  }}</div>
                  <count-to :start-val="0" :end-val="manageTitle?.storageUtilization" :decimals=2 suffix="%" :duration="1500" class="card-panel-num" />
                </dv-border-box-10>
              </div>
              <div class="specific-item">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div>{{  $t('productManagement.title6')  }}</div>
                  <count-to :start-val="0" :end-val="manageTitle?.inPalletCount" :duration="1500" class="card-panel-num" />
                </dv-border-box-10>
              </div>
              <div class="specific-item">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div>{{  $t('productManagement.title7')  }}</div>
                  <count-to :start-val="0" :end-val="manageTitle?.FIFO ? manageTitle?.FIFO * 100 : 0" suffix="%" :duration="1500" class="card-panel-num" />
                </dv-border-box-10>
              </div>
              <div class="specific-item">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div>{{  $t('productManagement.title8')  }}</div>
                  <count-to :start-val="0" :end-val="manageTitle?.skuCount" :duration="1500" class="card-panel-num" />
                </dv-border-box-10>
              </div>
            </div>
            <div class="two-item">
              <div class="center-left-table">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div class="content-title">{{  $t('productManagement.storageTitle')  }}</div>
                  <div style="width: 100%;" id="storage-inventory"></div>
                </dv-border-box-10>
              </div>
              <!-- 库龄分布 -->
              <div class="center-right-table">
                <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                  <div class="content-title">{{ $t('productManagement.storageAge') }}</div>
                  <div style="width: 100%;" id="storage-age"></div>
                </dv-border-box-10>
              </div>
            </div>
          </div>
          <div class="center-bottom">
            <div class="device-table">
              <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                <div class="content-title">{{  $t('productManagement.deviceStatus')  }}</div>
                <el-table empty-text="暂无数据" :data="deviceList" :row-class-name="tableRowClassName" :max-height="deviceMaxHeight">
                  <el-table-column prop="deviceName" :label="$t('productManagement.deviceName')">
                    <template slot-scope="scope">
                      {{ scope.row.deviceName }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="deviceCode" :label="$t('productManagement.deviceCode')" :width="170 / dpr"/>
                  <el-table-column prop="status" :label="$t('productManagement.deviceStatus2')" :width="80 / dpr">
                    <template slot-scope="scope">
                      <div
                        :style="{
                          margin: '0 auto',
                          textAlign: 'center',
                          background: `radial-gradient(circle, ${getColor(scope.row.status)} 50%, transparent 90%)`,
                          width: `${30 / dpr}px`,
                          height: `${30 / dpr}px`,
                          borderRadius: '50%',
                          boxShadow: `0 0 2px ${getColor(scope.row.light)}, 0px 0 2px ${getColor(scope.row.light)}, inset 0 0 10px rgba(255, 255, 255, 0.5)`
                        }"
                      ></div>
                    </template>
                  </el-table-column>
                  <el-table-column prop="startTime" :label="$t('productManagement.startTime')">
                    <template slot-scope="scope">
                      {{ formatTime(scope.row.startTime) }}
                    </template>
                  </el-table-column>
                </el-table>
              </dv-border-box-10>
            </div>
            <div class="device-chart">
              <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
                <div class="content-title">{{  $t('productManagement.deviceOee')  }}</div>
                <div style="width: 100%;" id="device-oee"></div>
              </dv-border-box-10>
            </div>
          </div>
        </div>
        <div class="right">
          <div class="right-top-table" style="overflow-x: hidden;">
            <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
              <div class="content-title">{{  $t('productManagement.outOrder')  }}</div>
              <div class="text-container" style="border: 1px solid #E4E7ED;padding: 5px;">
                <div class="each-item">
                  <div style="color: #fff;font-size: 1rem;font-weight: 600;">{{  $t('productManagement.allOrder')  }}</div>
                  <div style="color: #fff;font-size: 1rem;font-weight: 600;">{{ outOrderInfo?.allCount ? outOrderInfo.allCount : 0 }}</div>
                </div>
                <div class="each-item">
                  <div style="color: #fff;font-size: 1rem;font-weight: 600;">{{  $t('productManagement.already')  }}</div>
                  <div style="color: #fff;font-size: 1rem;font-weight: 600;">{{ outOrderInfo?.completeCount ? outOrderInfo.completeCount : 0 }}</div>
                </div>
                <div class="each-item">
                  <div style="color: #fff;font-size: 1rem;font-weight: 600;">{{  $t('productManagement.ing')  }}</div>
                  <div style="color: #67C23A;font-size: 1rem;font-weight: 600;">{{ outOrderInfo?.executedCount ? outOrderInfo.executedCount : 0 }}</div>
                </div>
                <div class="each-item">
                  <div style="color: #fff;font-size: 1rem;font-weight: 600;">{{  $t('productManagement.wait')  }}</div>
                  <div style="color: #fff;font-size: 1rem;font-weight: 600;">{{ outOrderInfo?.progressCount ? outOrderInfo.progressCount : 0 }}</div>
                </div>
              </div>
              <el-table empty-text="暂无数据" :data="outOrderList" :row-class-name="tableRowClassName" :max-height="outOrderMaxHeight">
                <el-table-column prop="outboundOrderNo" :label="$t('productManagement.allOrder')" />
                <el-table-column prop="customer" :label="$t('productManagement.customer')" :width="80 / dpr"/>
                <el-table-column prop="orderAllCount" :label="$t('productManagement.allPalletCode')" :width="75 / dpr"/>
                <el-table-column prop="orderCompletedCount" :label="$t('productManagement.alreadyPalletCode')" :width="80 / dpr" />
                <el-table-column :label="$t('productManagement.complete')" :width="80 / dpr">
                  <template slot-scope="scope">
                    {{ scope.row.orderCompletedCount / scope.row.orderAllCount * 100 || 0 }}%
                  </template>
                </el-table-column>
              </el-table>
            </dv-border-box-10>
          </div>
          <div class="right-bottom-table">
            <dv-border-box-10 class="content-border" :color="['rgb(35 135 188)', 'rgb(0, 187, 236)']">
              <div style="display: flex;flex-direction: column;height: 100%;">
                <div class="content-title">{{  $t('productManagement.containerInventory')  }}</div>
                <el-table empty-text="暂无数据" :data="containerInventoryList" :row-class-name="tableRowClassName" :max-height="containerMaxHeigth">
                  <el-table-column prop="containerCode" :label="$t('productManagement.containerCode')" />
                  <el-table-column prop="qty" :label="$t('productManagement.inventoryCount')" />
                  <el-table-column prop="level" :label="$t('productManagement.safeLevel')" />
                  <el-table-column prop="status" :label="$t('productManagement.containerStatus')" :width="75 / dpr">
                    <template slot-scope="scope">
                      <div
                        v-if="scope.row.light === 0"
                        :style="{
                          margin: '0 auto',
                          textAlign: 'center',
                          background: `radial-gradient(circle, ${getColor(scope.row.light)} 50%, transparent 90%)`,
                          width: `${30 / dpr}px`,
                          height: `${30 / dpr}px`,
                          borderRadius: '50%',
                          boxShadow: `0 0 2px ${getColor(scope.row.light)}, 0px 0 2px ${getColor(scope.row.light)}, inset 0 0 10px rgba(255, 255, 255, 0.5)`
                        }"
                      ></div>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </dv-border-box-10>
          </div>
        </div>
      </div>
    </dv-full-screen-container>
  </div>
</template>

<script>
import LangSelect from '@/components/LangSelect'
import Logo from '../assets/img/IWS_LOGO_N.png'
import * as echarts from 'echarts'
import CountTo from 'vue-count-to'
import { EventSourcePolyfill } from 'event-source-polyfill'
export default {
  name: 'Home',
  components: {
    CountTo,
    LangSelect
  },
  data() {
    return {
      language: this.$store.getters.language ? ( this.$store.getters.language === 'zh' ? false : true) : false,
      time: '',
      timer: [],
      es: null,
      // 图表
      hourFifoChart: null,
      dayFifoChart: null,
      storageUsageChart: null,
      deviceChart: null,
      storageAgeChart: null,
      // 图表数据
      inOutData: [],
      storageChartStorageData: [],
      storageChartAgeData: [],
      deviceData: [],
      deviceDate: [],
      // 列表
      deviceList: [],
      outOrderList: [],
      containerInventoryList: [],
      // 列表高度
      deviceMaxHeight: 0,
      outOrderMaxHeight: 0,
      containerMaxHeigth: 0,
      // 标题相关
      manageTitle: null,
      outOrderInfo: null,
      // 库存管理
      inventoryManage: null,
      // 冻结/先进先出
      fifoInfo: null,
      deviceManage: null,
      Logo: Logo,
      dpr: null
    }
  },
  mounted() {
    this.dpr = window.devicePixelRatio
    console.log(process.env.VUE_APP_BASE_API)
    this.getTime()
    this.timer = setInterval(() => {
      this.getTime()
    }, 1000)
    if (this.dpr) {
      this.getHead()
      this.createSSE()
      this.initAutoScroll()
    }
  },
  beforeDestroy() {
    clearInterval(this.timer)
  },
  methods: {
    createSSE() {
      const baseURL = process.env.VUE_APP_BASE_API
      this.es = new EventSourcePolyfill(`${baseURL}api/sse/manageDashboard`)
      this.es.onopen = () => {
        console.log('连接成功')
      }
      this.es.onclose = () => {
        console.log('连接断开')
      }
      this.es.onmessage = (e) => {
        const parsedData = JSON.parse(e.data)
        console.log(parsedData)
        // 标题相关
        this.manageTitle = parsedData.data.storageManage.manageTitleVo || {}
        // 设备相关
        this.deviceList = [{
          deviceName: this.$t('productManagement.stacker1'),
          deviceCode: this.$t('productManagement.stackerCode1'),
          status: 1,
          startTime: '2025-11-10 16:55:34'
        },{
          deviceName: this.$t('productManagement.stacker2'),
          deviceCode: this.$t('productManagement.stackerCode2'),
          status: 1,
          startTime: '2025-11-10 16:55:34'
        },{
          deviceName: this.$t('productManagement.stacker3'),
          deviceCode: this.$t('productManagement.stackerCode3'),
          status: 1,
          startTime: '2025-11-10 16:55:34'
        },{
          deviceName: this.$t('productManagement.stacker4'),
          deviceCode: this.$t('productManagement.stackerCode4'),
          status: 1,
          startTime: '2025-11-10 16:55:34'
        }]
        // 图表
        this.fifoInfo = parsedData.data.storageManage.fifoVo || {}
        this.deviceData = [
          this.$t('productManagement.stacker1'),
          this.$t('productManagement.stacker2'),
          this.$t('productManagement.stacker3'),
          this.$t('productManagement.stacker4')
        ]
        this.deviceDate = [98, 99, 99, 97]

        // 出货订单
        this.outOrderInfo = parsedData.data.storageManage?.outboundPrepVo || {}
        this.outOrderList = parsedData.data.storageManage?.outboundPrepVo?.outboundDetailList || []
        this.containerInventoryList = parsedData.data.storageManage?.containerVo?.containerDetailList || []

        // 进出库与饼图数据
        this.inOutData = parsedData.data.storageManage?.hourlyIoManageVo
        this.storageChartStorageData = parsedData.data.storageManage?.inventoryManageVo || {}
        this.storageChartAgeData = parsedData.data.storageManage?.inventoryAgeVo || {}

        this.initChart()
        this.getHeight()
      }
      this.es.onerror = (err) => {
        this.handleError()
        console.log(err)
      }
    },
    getHead() {
      setTimeout(() => {
        this.$nextTick(() => {
          const head = document.getElementsByClassName('el-table__header-wrapper')
          this.deviceMaxHeight = head[0].offsetHeight * 3
          this.outOrderMaxHeight = head[1].offsetHeight * 3
          this.containerMaxHeigth = head[2].offsetHeight * 3
        })
      }, 100)
    },
    getHeight() {
      this.$nextTick(() => {
        const head = document.getElementsByClassName('el-table__header-wrapper')
        if (this.deviceList.length === 0) {
          this.deviceMaxHeight = head[0].offsetHeight * 3
        }
        if (this.outOrderList.length === 0) {
          this.outOrderMaxHeight = head[1].offsetHeight * 3
        }
        if (this.containerInventoryList.length === 0) {
          this.containerMaxHeigth = head[2].offsetHeight * 3
        }
        // 步数
        // const box = document.getElementsByClassName('el-table__body-wrapper')
        // const boxStep = document.getElementsByClassName('el-table__body')
        // const targetScrollOne = (box[0].scrollTop + boxStep[0]?.children[1]?.children[0]?.offsetHeight) || 0
        // const targetScrollTwo = (box[1].scrollTop + boxStep[1]?.children[1]?.children[0]?.offsetHeight) || 0
        // const targetScrollThree = (box[2].scrollTop + boxStep[2]?.children[1]?.children[0]?.offsetHeight) || 0
        // 容器大小
        const oneTable = document.getElementsByClassName('device-table')[0].offsetHeight
        const twoTable = document.getElementsByClassName('right-top-table')[0].offsetHeight
        const threeTable = document.getElementsByClassName('right-bottom-table')[0].offsetHeight
        // 标题
        const eachTitle = document.getElementsByClassName('content-title')[0].offsetHeight
        // 右上统计条
        const textContainer = document.getElementsByClassName('text-container')[0].offsetHeight
        if (oneTable && this.deviceMaxHeight === head[0].offsetHeight * 3) {
          const adjustedHeight = oneTable - eachTitle
          // this.deviceMaxHeight = Math.floor(adjustedHeight / targetScrollOne) * targetScrollOne
          this.deviceMaxHeight = adjustedHeight - 10 / this.dpr
        }
        if (twoTable && this.outOrderMaxHeight === head[1].offsetHeight * 3) {
          const adjustedHeight = twoTable - eachTitle - textContainer
          // console.log(adjustedHeight)
          // this.outOrderMaxHeight = Math.floor(adjustedHeight / targetScrollTwo) * targetScrollTwo
          this.outOrderMaxHeight = adjustedHeight - 10 / this.dpr
        }
        if (threeTable && this.containerMaxHeigth === head[2].offsetHeight * 3) {
          const adjustedHeight = threeTable - eachTitle
          // this.containerMaxHeigth = Math.floor(adjustedHeight / targetScrollThree) * targetScrollThree
          this.containerMaxHeigth = adjustedHeight - 10 / this.dpr
        }
      })
    },
    initAutoScroll() {
      this.$nextTick(() => {
        const t = 3000 // 滚动间隔时间
        const box = document.getElementsByClassName('el-table__body-wrapper')
        const content = document.getElementsByClassName('el-table__body')
        const smoothScroll = (element, target) => {
          const start = element.scrollTop
          const change = target - start
          const duration = 1500
          let startTimestamp = null
          const step = (timestamp) => {
            if (!startTimestamp) startTimestamp = timestamp
            const time = timestamp - startTimestamp
            const current = easeInOutCubic(time, start, change, duration)
            element.scrollTop = current
            if (time < duration) requestAnimationFrame(step)
          }
          requestAnimationFrame(step)
        }
        const easeInOutCubic = (t, b, c, d) => {
          t /= d / 2
          if (t < 1) return c / 2 * t * t * t + b
          t -= 2
          return c / 2 * (t * t * t + 2) + b
        }
        this.timer = setInterval(() => {
          for (let i = 0; i < box.length; i++) {
            const wrapper = box[i]
            const contentEl = content[i]
            const rows = Array.from(contentEl.querySelectorAll('.el-table__row'))
            const scrollTop = wrapper.scrollTop
            const wrapperHeight = wrapper.offsetHeight
            const contentHeight = contentEl.scrollHeight
            let currentIndex = 0
            for (let j = 0; j < rows.length; j++) {
              if (rows[j].offsetTop <= scrollTop) currentIndex = j
              else break
            }
            const nextIndex = currentIndex + 1
            let targetScrollTop
            if (nextIndex >= rows.length || scrollTop + wrapperHeight >= contentHeight - 1) {
              targetScrollTop = 0
            } else {
              targetScrollTop = rows[nextIndex].offsetTop
            }
            smoothScroll(wrapper, targetScrollTop)
          }
        }, t)
      })
    },
    formatTime(time) {
      if (!time) return '';
      const date = new Date(time);
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      const hours = String(date.getHours()).padStart(2, '0');
      const minutes = String(date.getMinutes()).padStart(2, '0');
      const seconds = String(date.getSeconds()).padStart(2, '0');
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    },
    getColor(val) {
      switch (val) {
        case 1:
          return '#67C23A';
        case 0:
          return '#ff0000';
        default:
          return '#fff';
      }
    },
    initChart() {
      // 储位利用率
      const storageUsageDom = document.getElementById('storage-usage')
      if (!this.storageUsageChart) {
        this.storageUsageChart = echarts.init(storageUsageDom)
      }
      let option1
      option1 = {
        series: [
          {
            type: 'gauge',
            axisLine: {
              lineStyle: {
                width: 22.5 / this.dpr,
                color: [
                  [0.7, {
                    type: 'linear',
                    x: 0, y: 0, x2: 1, y2: 0,
                    colorStops: [
                      { offset: 0, color: '#34c759' },
                      { offset: 1, color: '#f7a801' }
                    ]
                  }],
                  [0.9, {
                    type: 'linear',
                    x: 0, y: 0, x2: 1, y2: 0,
                    colorStops: [
                      { offset: 0, color: '#f7a801' },
                      { offset: 1, color: '#e53935' }
                    ]
                  }],
                  [1, '#e53935']
                ]
              }
            },
            pointer: {
              itemStyle: { color: 'auto' },
              width: 7.5 / this.dpr
            },
            axisTick: {
              distance: -(22.5 / this.dpr),
              length: 15 / this.dpr,
              lineStyle: { color: '#fff', width: 1 }
            },
            splitLine: {
              distance: -(22.5 / this.dpr),
              length: 15 / this.dpr,
              lineStyle: { color: '#fff', width: 1 }
            },
            axisLabel: {
              color: '#fff',
              distance: 30 / this.dpr,
              fontSize: 21 / this.dpr
            },
            detail: {
              valueAnimation: true,
              formatter: '{value} %',
              color: '#fff',
              fontSize: 24 / this.dpr
            },
            data: [
              {
                // 更稳健：防止 storageUtilization 未定义时报错
                value: this.manageTitle?.storageUtilization != null
                  ? +Number(this.manageTitle.storageUtilization).toFixed(2)
                  : 0
              }
            ]
          }
        ]
      }
      this.storageUsageChart.setOption(option1)

      // 设备OEE
      const deviceDom = document.getElementById('device-oee')
      if (!this.deviceChart) {
        this.deviceChart = echarts.init(deviceDom)
      }
      let option2
      option2 = {
        grid: { top: 50, bottom: 20, left: 50, right: 20 },
        tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, formatter: '{b}: {c}%' },
        legend: { orient: 'horizontal', top: 10, textStyle: { color: '#fff' } },
        xAxis: {
          type: 'category',
          data: this.deviceData,
          axisLabel: { fontSize: 12, color: '#fff', fontWeight: 'bold' }
        },
        yAxis: {
          type: 'value',
          axisLabel: { fontSize: 14, color: '#fff', fontWeight: 'bold', formatter: '{value}%' },
          min: 0, max: 100
        },
        series: [
          {
            data: this.deviceDate,
            name: this.$t('productManagement.run'),
            type: 'bar',
            barWidth: `${40 / this.dpr}`,
            barCategoryGap: '40%',
            label: { show: true, position: 'top', color: '#fff', fontSize: 12, fontWeight: 'bold', formatter: '{c}%' },
            itemStyle: {
              color: {
                type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
                colorStops: [{ offset: 0, color: '#B7EB8F' }, { offset: 1, color: '#67C23A' }]
              }
            },
            showBackground: true,
            backgroundStyle: { color: 'rgba(180, 180, 180, 0.2)' }
          }
        ]
      }
      this.deviceChart.setOption(option2)

      // 库存占比
      const inventoryData = [
        { name: this.$t('productManagement.product'), color: '#4CD964' },
        { name: this.$t('productManagement.container'), color: '#5AC8FA' },
        { name: this.$t('productManagement.emptyPallet'), color: '#FFD539' },
      ]
      const storageInventoryDom = document.getElementById('storage-inventory')
      if (!this.inventoryManage) {
        this.inventoryManage = echarts.init(storageInventoryDom)
      }
      let option6
      option6 = {
        grid: { top: 30, bottom: 0, left: 0, right: 0 },
        tooltip: { trigger: 'item', formatter: '{a} <br/>{b} : {c} ({d}%)' },
        legend: {
          top: 10, left: 'center',
          data: inventoryData.map(item => item.name),
          textStyle: { color: '#fff', fontSize: 12 / this.dpr, fontWeight: 500 }
        },
        series: [
          {
            name: this.$t('productManagement.storageRate'),
            type: 'pie',
            radius: `${85 - 20 * this.dpr}%`,
            center: ['50%', '50%'],
            selectedMode: 'single',
            color: inventoryData.map(item => item.color),
            data: [
              { value: this.storageChartStorageData.productPart, name: this.$t('productManagement.product') },
              { value: this.storageChartStorageData.containerPart, name: this.$t('productManagement.container') },
              { value: this.storageChartStorageData.parentPalletPart, name: this.$t('productManagement.emptyPallet') }
            ],
            label: { show: true, position: 'outside', formatter: '{d}%', color: '#fff', fontSize: 14 / this.dpr, fontWeight: 700 },
            labelLine: { show: true, length: 10 / this.dpr, length2: 15 / this.dpr, lineStyle: { color: '#fff' } },
            emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' }, label: { color: '#fff', fontSize: 14 } }
          }
        ]
      }
      this.inventoryManage.setOption(option6)

      // ======== 库龄（关键修改：固定颜色 + 0 值不显示标签/引导线，不再过滤项） ========
      const storageAgeDom = document.getElementById('storage-age')
      if (!this.storageAgeChart) {
        this.storageAgeChart = echarts.init(storageAgeDom)
      }

      // 固定类别及颜色（顺序恒定）
      const AGE_BUCKETS = [
        { key: 'level1', name: this.$t('productManagement.tip1'), color: '#64B5F6' },  // <5
        { key: 'level2', name: this.$t('productManagement.tip2'), color: '#2ECC71' },  // 5~15
        { key: 'level3', name: this.$t('productManagement.tip3'), color: '#FDD835' },  // 15~30
        { key: 'level4', name: this.$t('productManagement.tip4'), color: '#FF9800' },  // 30~90
        { key: 'level5', name: this.$t('productManagement.tip5'), color: '#F44336' },  // >90
      ]

      // 构造数据：0 值不显示 label/labelLine，但数据项保留以固定颜色对应关系
      const ageData = AGE_BUCKETS.map(b => {
        const val = Number(this.storageChartAgeData?.[b.key]) || 0
        return {
          name: b.name,
          value: val,
          itemStyle: { color: b.color },
          label: {
            show: val > 0,
            position: 'outside',
            formatter: ({ percent }) => `${Math.round(percent)}%`,
            color: '#fff',
            fontSize: 14 / this.dpr,
            fontWeight: 700
          },
          labelLine: {
            show: val > 0,
            length: 10 / this.dpr,
            length2: 15 / this.dpr,
            lineStyle: { color: '#fff' }
          }
        }
      })
      const totalAge = ageData.reduce((s, d) => s + d.value, 0)

      const option3 = {
        grid: { top: 30, bottom: 0, left: 0, right: 0 },
        tooltip: {
          trigger: 'item',
          formatter: ({ name, value, percent }) => !value ? `${name}: 0` : `${name} : ${value} (${Math.round(percent)}%)`
        },
        legend: {
          top: 10,
          left: 'center',
          data: AGE_BUCKETS.map(i => i.name),
          textStyle: { color: '#fff', fontSize: 12 / this.dpr, fontWeight: 500 },
          icon: 'circle',
          itemWidth: 10,
          itemHeight: 10
        },
        series: [
          {
            name: this.$t('productManagement.storageRate'),
            type: 'pie',
            radius: `${85 - 20 * this.dpr}%`,
            center: ['50%', '50%'],
            selectedMode: 'single',
            colorBy: 'data',            // 颜色由每个数据项决定
            emphasis: { scale: false }, // 防止 0 值项被高亮放大
            label: { show: true, position: 'outside' },     // 实际显示由各项覆盖
            labelLine: { show: true },
            data: ageData
          }
        ],
        graphic: totalAge === 0 ? [{
          type: 'text',
          left: 'center',
          top: 'middle',
          style: {
            text: this.$t('common.noData') || '暂无数据',
            fill: '#ffffff',
            fontSize: 14 / this.dpr,
            fontWeight: 600
          }
        }] : []
      }

      // notMerge=true，确保每次完全应用新配置（避免历史配置影响）
      this.storageAgeChart.setOption(option3, true)
      // ======== 库龄 结束 ========

      // 分时出入库
      const hourFifoDom = document.getElementById('hour-fifo')
      if (!this.hourFifoChart) {
        this.hourFifoChart = echarts.init(hourFifoDom)
      }
      let option4
      option4 = {
        grid: { top: 40, bottom: 30, left: 40, right: 10 },
        tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
        legend: { orient: 'horizontal', top: 10, textStyle: { color: '#fff', fontSize: 12 / this.dpr } },
        xAxis: [
          {
            type: 'category',
            data: this.inOutData.timeList,
            axisLabel: { fontSize: 8, color: '#fff', fontWeight: 'bold' }
          }
        ],
        yAxis: [
          { type: 'value', axisLabel: { fontSize: 14 / this.dpr, color: '#fff', fontWeight: 'bold' } }
        ],
        series: [
          {
            name: this.$t('productManagement.out'),
            type: 'bar',
            stack: 'same',
            emphasis: { focus: 'series' },
            barWidth: 20 / this.dpr,
            barCategoryGap: '40%',
            itemStyle: {
              color: {
                type: 'linear', x: 0, y: 1, x2: 0, y2: 0,
                colorStops: [{ offset: 0, color: '#FF8C00' }, { offset: 1, color: '#FFA500' }]
              }
            },
            data: this.inOutData.outQtyList
          },
          {
            name: this.$t('productManagement.in'),
            type: 'bar',
            stack: 'same',
            emphasis: { focus: 'series' },
            barWidth: 20 / this.dpr,
            barCategoryGap: '40%',
            itemStyle: {
              color: {
                type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
                colorStops: [{ offset: 0, color: '#B0E0E6' }, { offset: 1, color: '#56A5EC' }],
                global: false
              }
            },
            data: this.inOutData.inQtyList
          }
        ]
      }
      this.hourFifoChart.setOption(option4)

      // 日出入库
      const dayFifoDom = document.getElementById('day-fifo')
      if (!this.dayFifoChart) {
        this.dayFifoChart = echarts.init(dayFifoDom)
      }
      let option5
      option5 = {
        grid: { top: 40, bottom: 30, left: 40, right: 10 },
        tooltip: { trigger: 'axis' },
        legend: { orient: 'horizontal', top: 10, textStyle: { color: '#fff', fontSize: 12 / this.dpr } },
        xAxis: {
          type: 'category',
          data: this.inOutData.dayTimeList.map(item => item.slice(5)),
          axisLabel: { fontSize: 8, color: '#fff', fontWeight: 'bold' }
        },
        yAxis: { type: 'value', axisLabel: { fontSize: 14 / this.dpr, color: '#fff', fontWeight: 'bold' } },
        series: [
          {
            name: this.$t('productManagement.out'),
            type: 'line',
            data: this.inOutData.dayOutQtyList,
            itemStyle: { color: '#FF9500' },
            label: { show: true, position: 'top', color: '#fff', fontSize: 14 / this.dpr }
          },
          {
            name: this.$t('productManagement.in'),
            type: 'line',
            data: this.inOutData.dayInQtyList,
            itemStyle: { color: '#71b7ea' },
            label: { show: true, position: 'top', color: '#fff', fontSize: 14 / this.dpr }
          }
        ]
      }
      this.dayFifoChart.setOption(option5)
    },
    handleError() {
      if (this.es.readyState === EventSourcePolyfill.CLOSED) {
        this.es.close()
        this.createSSE()
      } else if (this.es.readyState === EventSourcePolyfill.CONNECTING) {
        console.log('正在重连中')
      }
    },
    tableRowClassName({ rowIndex }) {
      if (rowIndex % 2 === 1) {
        return 'warning-row'
      } else {
        return 'success-row'
      }
    },
    getTime() {
      let yy = new Date().getFullYear()
      let mm = new Date().getMonth() + 1
      let dd = new Date().getDate()
      let hh = new Date().getHours() < 10 ? '0' + new Date().getHours() : new Date().getHours()
      let mf = new Date().getMinutes() < 10 ? '0' + new Date().getMinutes() : new Date().getMinutes()
      let ss = new Date().getSeconds() < 10 ? '0' + new Date().getSeconds() : new Date().getSeconds()
      this.time = yy + '-' + mm + '-' + dd + ' ' + hh + ':' + mf + ':' + ss
    },
    languageChange(e) {
      console.log(e)
      if (e === true) {
      //   this.language = 'en'
        this.$i18n.locale = 'en'
        this.$store.dispatch('app/setLanguage', 'en')
      } else {
      //   this.language = 'zh'
        this.$i18n.locale = 'zh'
        this.$store.dispatch('app/setLanguage', 'zh')
      }
    }
  },
}
</script>

<style lang="less" scoped>
/deep/ .el-switch__label {
  color: #fff !important; 
}
.container {
  // background: rgb(0, 116, 194);
  background-image: url('../assets/img/1-背景.png');
  background-size: 100% 100%;
  height: 100%;
}
.red { width: 20px; height: 20px; border-radius: 50%; background-color: #ff0000; margin-left: 45px; }
.green { width: 20px; height: 20px; border-radius: 50%; background-color: #06eb00; margin-left: 45px; }
.yellow { width: 20px; height: 20px; border-radius: 50%; background-color: #ffee00; margin-left: 45px; }

.header {
  text-align: center;
  background-image: url('../assets/img/2-标题23.png');
  background-size: 100% 110%;
  height: 5%;
  h1 { margin: 0; color: #fff; font-size: 40px; }
  .title { position: relative; }
  .logo { position: absolute; left: 1%; top: 0px; display: flex; gap: 10px; }
  .time { position: absolute; right: 2%; color: #fff; top: 0.5%; font-size: 24px; font-weight: bold; }
}

.body {
  width: 99%;
  height: 94%;
  display: flex;
  box-sizing: border-box;
  gap: 5px;
  margin: 5px auto;
  .content-title { box-sizing: border-box; color: #fff; text-align: center; font-size: 1.8rem; font-weight: 600; }
  .basic-title { padding: 10px; box-sizing: border-box; color: #fff; text-align: center; font-size: 1.5rem; font-weight: 600; }
  .text-container {
    display: flex; justify-content: space-between; margin: 5px 0;
    .each-item {
      flex: 1; text-align: center;
      .white-item { color: #fff; font-size: 1.5rem; font-weight: 600; }
      .red-item { color: #F56C6C; font-size: 1.5rem; font-weight: 600; }
      .green-item { color: #67C23A; font-size: 1.5rem; font-weight: 600; }
    }
  }
  .left {
    width: 20%; display: flex; flex-direction: column; gap: 5px;
    .left-top {
      flex: 2;
      #storage-usage { height: 100%; }
    }
    .left-bottom {
      flex: 3;
      #hour-fifo { width: 100%; height: 100%; }
      #day-fifo { width: 100%; height: 100%; }
    }
  }
  .center {
    width: 57%; display: flex; flex-direction: column; gap: 5px;
    .center-center {
      flex: 6; display: flex; flex-direction: column; gap: 5px;
      .four-item {
        flex: 1; display: flex; gap: 5px;
        .specific-item {
          flex: 1; color: #fff; text-align: center; font-size: 20px; line-height: 40px; font-weight: bold;
          .card-panel-num { color: #3de7c9; font-size: 30px; display: block; }
        }
        .center-left-table { flex: 1; height: 100%; }
        .center-right-table { flex: 1; height: 100%; }
      }
      .two-item {
        display: flex; gap: 5px; flex: 4;
        .center-left-table {
          width: 50%; height: 100%;
          #storage-inventory { height: 85%; }
        }
        .center-right-table {
          width: 50%; height: 100%;
          #storage-age { height: 85%; }
        }
      }
    }
    .center-bottom {
      flex: 4; display: flex; gap: 5px;
      .device-table { flex: 1; height: 100%; }
      .device-chart { flex: 1; height: 100%;
        #device-oee { height: 85%; }
      }
    }
  }
  .right {
    width: 23%; display: flex; flex-direction: column; gap: 5px;
    .right-top-table{ flex: 2; height: 100%; }
    .right-bottom-table{ flex: 3; height: 100%; }
  }
}

/* ------------------------------el-table--------------------- */
 /deep/ .el-table { margin: 0 !important; }
 /deep/ .el-table__body { width: 100% !important; }
 /deep/ tr td .cell { font-size: larger !important; }
 /deep/ .el-table__header-wrapper {
  .el-table__header {
    width: 100% !important;
    [name="gutter"] { display: none !important; }
  }
  th.el-table__cell.gutter { display: none !important; }
}
 /deep/ .el-table__header tr .el-table__cell {
  background: linear-gradient(to bottom, #054ea2, #023575, #002a5e);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
.el-table__body tr:hover > td { background-color: #1f68ddc0 !important; }
.el-table th.el-table__cell { background-color: rgba(8, 119, 223, 0.6); }
 /deep/ .el-table th.el-table__cell > .cell { font-size: 18px !important; }
.el-table--border { border: none; }
.el-table, .el-table__expanded-cell { background-color: transparent; }
 /deep/ .el-table__body-wrapper { background-color: rgba(19, 95, 236, 0.2) !important; }
.el-table th, .el-table tr, .el-table td { background-color: transparent; color: #fff ; border-color: transparent !important; }
 /deep/.el-table .warning-row { background: rgba(38, 66, 105, 0.5) !important; }
 /deep/.cell { text-align: center; }
 /deep/.el-table .success-row {
  background-image: linear-gradient(
    to left,
    rgba(3, 58, 141, 0.685) 0%,
    rgba(15, 30, 56, 0.8) 65%,
    rgba(22, 58, 109, 0.699) 100%
  );
}
.el-table::before { display: none !important; }
.content-border ::-webkit-scrollbar { width: 0px; }
</style>
